package com.qidian.tcba.admin.service.impl;

import com.qidian.tcba.admin.model.dto.assignTask.ResultAssignTaskDTO;
import com.qidian.tcba.admin.model.dto.assignTask.SubmitAssignTaskDTO;
import com.qidian.tcba.admin.model.dto.parkLot.*;
import com.qidian.tcba.admin.model.query.ParkLotRecordManageQueryDTO;
import com.qidian.tcba.admin.model.dto.parkLotManage.ParkLotRecordManageResultDTO;
import com.qidian.tcba.admin.model.dto.parkLotRecord.*;
import com.qidian.tcba.admin.model.entity.*;
import com.qidian.tcba.admin.service.AttachmentService;
import com.qidian.tcba.admin.service.ParkLotRecordTaskService;
import com.qidian.tcba.dao.*;
import com.qidian.tcba.oss.service.AttachmentsService;
import com.qidian.tcba.utils.*;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.lang.reflect.InvocationTargetException;
import java.text.Format;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author:fyl
 * @date 2021/7/6 15:08
 * @Modified By:
 * @Modified Date:
 * @Description:
 */
@Service
public class ParkLotRecordTaskServiceImpl implements ParkLotRecordTaskService {

    private final ParkLotRecordTaskMapper parkLotRecordTaskMapper;

    private final RecordProcessMapper recordProcessMapper;

    private final AttachmentService attachmentService;

    private final AttachmentsService ossAttachmentService;

    private final ParkLotRecordAuditRecordMapper parkLotRecordAuditRecordMapper;

    private final ParkLotRecordAssignTaskItemMapper parkLotRecordAssignTaskItemMapper;

    private final ParkLotRecordTaskLastChangeMapper parkLotRecordTaskLastChangeMapper;

    private final DistrictMapper districtMapper;

    private final ParkLotRecordProcessHistoryMapper parkLotRecordProcessHistoryMapper;

    private final UserMapper userMapper;

    private final UserExtendMsgMapper userExtendMsgMapper;

    private final ParkLotRecordAssignTaskMapper parkLotRecordAssignTaskMapper;

    public ParkLotRecordTaskServiceImpl(ParkLotRecordTaskMapper parkLotRecordTaskMapper,
                                        RecordProcessMapper recordProcessMapper,
                                        AttachmentService attachmentService,
                                        AttachmentsService ossAttachmentService,
                                        ParkLotRecordAuditRecordMapper parkLotRecordAuditRecordMapper,
                                        ParkLotRecordAssignTaskItemMapper parkLotRecordAssignTaskItemMapper,
                                        ParkLotRecordTaskLastChangeMapper parkLotRecordTaskLastChangeMapper,
                                        DistrictMapper districtMapper,
                                        ParkLotRecordProcessHistoryMapper parkLotRecordProcessHistoryMapper,
                                        UserMapper userMapper, UserExtendMsgMapper userExtendMsgMapper,
                                        ParkLotRecordAssignTaskMapper parkLotRecordAssignTaskMapper) {
        this.parkLotRecordTaskMapper = parkLotRecordTaskMapper;
        this.recordProcessMapper = recordProcessMapper;
        this.attachmentService = attachmentService;
        this.ossAttachmentService = ossAttachmentService;

        this.parkLotRecordAuditRecordMapper = parkLotRecordAuditRecordMapper;
        this.parkLotRecordAssignTaskItemMapper = parkLotRecordAssignTaskItemMapper;
        this.parkLotRecordTaskLastChangeMapper = parkLotRecordTaskLastChangeMapper;
        this.districtMapper = districtMapper;
        this.parkLotRecordProcessHistoryMapper = parkLotRecordProcessHistoryMapper;
        this.userMapper = userMapper;
        this.userExtendMsgMapper = userExtendMsgMapper;
        this.parkLotRecordAssignTaskMapper = parkLotRecordAssignTaskMapper;
    }

    @Override
    public ParkStatusDataDTO getParkStatusData(int userId) {
        List<ParkLotRecordTask> userParkLotRecord = parkLotRecordTaskMapper.getUserParkLotRecord(userId);
        int hold = 0;
        int inReview = 0;
        int returned = 0;
        int finished = 0;
        int cancelled = 0;
        for (ParkLotRecordTask task : userParkLotRecord) {
            int status = task.getStatus();
            switch (status) {
                case 0:
                    hold++;
                    break;
                case 1:
                    inReview++;
                    break;
                case 2:
                    returned++;
                    break;
                case 3:
                    finished++;
                    break;
                case 4:
                    cancelled++;
                    break;
            }
        }

        return new ParkStatusDataDTO(hold, inReview, returned, finished, cancelled);
    }

    @Override
    public List<ParkRecordListDTO> getParkRecordList(int status, int userId, int page, int size) {
        int index = (page - 1) * size;
        return parkLotRecordTaskMapper.getParkRecordList(status, userId, index, size);
    }

    @Override
    public int getParkRecordNumber(int userId) {
        return parkLotRecordTaskMapper.getParkRecordNumber(userId);
    }

    @Override
    public List<RecentRecordStageDTO> getRecentRecordList(int userId) {
        List<RecentRecordStageDTO> recentRecordList = parkLotRecordTaskMapper.getRecentRecordList(userId);
        recentRecordList.removeIf(recentRecordStageDTO -> recentRecordStageDTO.getStatus() == 3);
        //将状态改变便于排序
        for (RecentRecordStageDTO recentRecord : recentRecordList) {
            if (recentRecord.getStatus() == 0) {
                recentRecord.setStatus(Integer.MAX_VALUE);
            }
        }
        recentRecordList.sort(new Comparator<RecentRecordStageDTO>() {
            @Override
            public int compare(RecentRecordStageDTO o1, RecentRecordStageDTO o2) {
                return Integer.compare(o1.getStatus(), o2.getStatus());
            }
        });
        //改回原来的状态
        if (recentRecordList.size() >= 2) {
            for (RecentRecordStageDTO recentRecord : recentRecordList) {
                if (recentRecord.getStatus() == Integer.MAX_VALUE) {
                    recentRecord.setStatus(0);
                }
            }
            return recentRecordList.subList(0, 2);
        }
        return recentRecordList;
    }

    /**
     * 获取流水号
     *
     * @param districtName
     * @return
     */
    public String getSno(String districtName) {
        //获取当天备案数
        Format sdf = new SimpleDateFormat("yyyy-MM-dd");
        int dayCount = parkLotRecordTaskMapper.getTimeCount(sdf.format(new Date()));
        //流水号日期格式
        Format sdfSno = new SimpleDateFormat("yyyyMMdd");
        //获取区县代码
        District district = districtMapper.selectByName(districtName);
        return district.getAdcode().substring(district.getAdcode().length() - 2) + sdfSno.format(new Date()) + dayCount + 1;
    }

    @Override
    public ParkLotInfoDTO holdParkRecord(ParkLotSubmitDTO parkLotSubmitDTO,
                                         int userId) throws InvocationTargetException, IllegalAccessException {
        //复制属性
        ParkLotRecordTask parkLot = new ParkLotRecordTask();
        SpringUtils.copyPropertiesIgnoreNull(parkLotSubmitDTO, parkLot);
        handParkLotRecord(parkLot, parkLotSubmitDTO.getAttachIds(), userId);
        return getParkLotInfo(parkLotRecordTaskMapper.getParkIdByName(parkLot.getName()));
    }

    @Transactional
    @Override
    public void submitParkRecord(ParkLotSubmitDTO parkLotSubmitDTO,
                                 int userId) throws InvocationTargetException, IllegalAccessException {
        //复制属性
        ParkLotRecordTask parkLot = BeanMapper.map(parkLotSubmitDTO, ParkLotRecordTask.class);
        parkLot.setSubmitedAt(new Date());
        parkLot.setCompletedAt(new Date());
        //设置流水号
//        String[] district = parkLot.getDistrictName().split(",");
//        String[] split = district[0].split(":");
//        //设置区县的id和名字
//        parkLot.setDistrictId(Integer.parseInt(split[0]));
//        parkLot.setDistrictName(split[1]);
//        //设置街道的id
//        parkLot.setDistrictStreetId(Integer.parseInt(district[1].split(":")[0]));
//        parkLot.setSno(getSno(parkLot.getDistrictName()));
        //区域id
        Integer areaRegionId = districtMapper.getAreaRegionIdByDistinctId(parkLot.getDistrictId());
        if (areaRegionId != null) {
            parkLot.setAreRegionId(areaRegionId);
        }
        String[] position = parkLot.getPositionProperty().split(",");
        for (String s : position) {
            if (s.equals("重要商圈")) {
                parkLot.setIsInImportantBusinessCircle(1);
            } else {
                parkLot.setIsInImportantBusinessCircle(0);
            }

        }
        //将状态设为初审
        parkLot.setStage(1);
        parkLot.setStatus(1);
        parkLot.setAuditStatus(1);
        parkLot.setSubmitedAt(new Date());
        handParkLotRecord(parkLot, parkLotSubmitDTO.getAttachIds(), userId);
    }

    /**
     * 处理暂存和提交时数据库的记录
     *
     * @param parkLot
     * @param attachIds
     * @param userId
     */
    public void handParkLotRecord(ParkLotRecordTask parkLot, List<Integer> attachIds, int userId) {
        parkLot.setUserId(userId);
        String[] district = parkLot.getDistrictName().split(",");
        String[] split = district[0].split(":");
        //设置区县的id和名字
        parkLot.setDistrictId(Integer.parseInt(split[0]));
        parkLot.setDistrictName(split[1]);
        //设置街道的id
        parkLot.setDistrictStreetId(Integer.parseInt(district[1].split(":")[0]));
        parkLot.setSno(getSno(parkLot.getDistrictName()));
        //公司id
        UserExtendMsg userOrgMsg = userExtendMsgMapper.getUserOrgMsg(userId);
        parkLot.setManageOrgId(userOrgMsg.getOrgId());
        Integer parkId = parkLotRecordTaskMapper.getParkIdByName(parkLot.getName());
        if (parkId == null) {
            //第一次提交时间
            parkLot.setFirstSubmitedAt(new Date());
            parkLotRecordTaskMapper.insert(parkLot);
            parkId = parkLot.getId();
        } else {
            parkLot.setId(parkId);
            parkLotRecordTaskMapper.updateByPrimaryKey(parkLot);
        }
        //添加流程履历表记录
        Date date = new Date();
        String username = userMapper.selectByPrimaryKey(userId).getUsername();
        ParkLotRecordProcessHistory history = new ParkLotRecordProcessHistory(null, parkId, 0, username, date, date, 1);
        parkLotRecordProcessHistoryMapper.insert(history);
        //添加审核记录表记录
        ParkLotRecordAuditRecord parkLotRecordAuditRecord = new ParkLotRecordAuditRecord(parkId, history.getId(), 0, 0, 1, userId, username, "审核通过");
        parkLotRecordAuditRecordMapper.insert(parkLotRecordAuditRecord);
        //关联附件
        if (attachIds != null && attachIds.size() != 0) {
            ossAttachmentService.relateAttach(parkId, TablesName.PARK_LOT_RECORD_TASK_NAME, attachIds);
        }
    }

    @Override
    public ParkLotInfoDTO getParkLotInfo(int id) {
        return new ParkLotInfoDTO(
                getParkLotSno(id),
                getParkLotManagerBaseInfo(id),
                getParkLotBaseInfo(id),
                getParkLotSettingInfo(id),
                attachmentService.getParkLotAttachmentsInfo(id)
        );
    }

    @Override
    public String getParkLotSno(int taskId) {
        return parkLotRecordTaskMapper.getParkLotSno(taskId);
    }


    @Override
    public ParkLotBaseInfoDTO getParkLotBaseInfo(int id) {
        ParkLotBaseInfoDTO parkLotBaseInfo = parkLotRecordTaskMapper.getParkLotBaseInfo(id);
        parkLotBaseInfo.setParkLotList(
                ossAttachmentService.findByOwner(TablesName.PARK_LOT_RECORD_TASK_NAME, id, BusinessType.PARK_LOT_LIST));
        parkLotBaseInfo.setConfirmationOfCompletion(
                ossAttachmentService.findByOwner(TablesName.PARK_LOT_RECORD_TASK_NAME, id, BusinessType.CONFIRMATION_OF_COMPLETION));
        parkLotBaseInfo.setChargePilesEvidentialMaterial(
                ossAttachmentService.findByOwner(TablesName.PARK_LOT_RECORD_TASK_NAME, id, BusinessType.CHARGE_PILES_EVIDENTIAL_MATERIAL));
        return parkLotBaseInfo;
    }

    @Override
    public ParkLotManagerBaseInfoDTO getParkLotManagerBaseInfo(int id) {
        ParkLotManagerBaseInfoDTO parkLotManagerBaseInfo = parkLotRecordTaskMapper.getParkLotManagerBaseInfo(id);
        parkLotManagerBaseInfo.setFeeDiscountExplain(ossAttachmentService.findByOwner(TablesName.PARK_LOT_RECORD_TASK_NAME, id, BusinessType.FEE_DISCOUNT_EXPLAIN));
        parkLotManagerBaseInfo.setBusinessLicense(ossAttachmentService.findByOwner(TablesName.PARK_LOT_RECORD_TASK_NAME, id, BusinessType.BUSINESS_LICENSE));
        parkLotManagerBaseInfo.setPropertyRight(ossAttachmentService.findByOwner(TablesName.PARK_LOT_RECORD_TASK_NAME, id, BusinessType.PROPERTY_RIGHT));
        parkLotManagerBaseInfo.setRecommendation(ossAttachmentService.findByOwner(TablesName.PARK_LOT_RECORD_TASK_NAME, id, BusinessType.RECOMMENDATION));
        parkLotManagerBaseInfo.setPermissionRight(ossAttachmentService.findByOwner(TablesName.PARK_LOT_RECORD_TASK_NAME, id, BusinessType.PERMISSION_RIGHT));
        return parkLotManagerBaseInfo;
    }

    @Override
    public ParkLotSettingInfoDTO getParkLotSettingInfo(int id) {
        return parkLotRecordTaskMapper.getParkLotSettingInfo(id);
    }

    @Override
    public ParkLotReformDTO getParkReformInfo(int parkTaskId, int stage) {
        //整改任务
        ParkLotRecordAuditRecord auditRecords = parkLotRecordAuditRecordMapper.getAuditRecordsByRecordTaskId(parkTaskId, stage, 0);
        if (auditRecords == null) {
            throw new BusinessException(new Message("整改项不存在"));
        }
        ParkLotReformDTO reformDTO = BeanMapper.map(auditRecords, ParkLotReformDTO.class);
        List<ParkLotRecordAssignTask> assignTask = parkLotRecordAssignTaskMapper.getAssignTask(auditRecords.getId());
        List<ResultAssignTaskDTO> assignTaskDTOS = BeanMapper.mapList(assignTask, ResultAssignTaskDTO.class);
        reformDTO.setResultAssignTasks(assignTaskDTOS);
        //停车场基本信息
        reformDTO.setParkLotInfo(getParkLotInfo(parkTaskId));
        //审核意见名称
        String name = reformDTO.getParkLotInfo().getParkLotManagerBaseInfoDTO().getName();
        switch (stage) {
            case 1:
                name += "资料初审意见";
                break;
            case 2:
                name += "现场勘察意见";
                break;
            case 3:
                name += "镇级备案审核意见";
                break;
        }
        Date createdAt = auditRecords.getCreatedAt();
        Format format = new SimpleDateFormat("yyyyMMdd HH:mm");
        name += "_" + format.format(createdAt);
        reformDTO.setName(name);
        return reformDTO;
    }

    @Transactional
    @Override
    public boolean submitReformInfo(ParkLotReformSubmitDTO parkLotReformSubmitDTO) {
        ParkLotRecordTask map = BeanMapper.map(parkLotReformSubmitDTO, ParkLotRecordTask.class);
        parkLotRecordTaskMapper.updateByPrimaryKey(map);
        List<SubmitAssignTaskDTO> submitAssignTaskDTOList = parkLotReformSubmitDTO.getSubmitAssignTaskDTOList();
        for (SubmitAssignTaskDTO submitAssignTaskDTO : submitAssignTaskDTOList) {
            //添加整改项
            ParkLotRecordAssignTaskItem parkLotRecordAssignTaskItem = new ParkLotRecordAssignTaskItem(null, submitAssignTaskDTO.getId(),
                    submitAssignTaskDTO.getName(), parkLotReformSubmitDTO.getIsFinished());
            parkLotRecordAssignTaskItemMapper.insert(parkLotRecordAssignTaskItem);
            //关联附件
            if (submitAssignTaskDTO.getAssignTaskItemIds().size() != 0) {
                ossAttachmentService.relateAttach(parkLotRecordAssignTaskItem.getId(),
                        TablesName.PARK_LOT_RECORD_ASSIGN_TASK_ITEM,
                        submitAssignTaskDTO.getAssignTaskItemIds());
            }
        }

//        if (assignTaskItemIds.size() != 0) {
//            ossAttachmentService.relateAttach(, TablesName.PARK_LOT_RECORD_ASSIGN_TASK_ITEM, assignTaskItemIds);
//        }
//        List<AssignTaskItemDTO> assignTaskItems = parkLotReform.getAssignTaskItems();
//        for (AssignTaskItemDTO assignTaskItem : assignTaskItems) {
//            if (assignTaskItem.getStatus() == 0) {
//                return false;
//            }
//        }
//        //更新备案信息
////        submitParkRecord(parkLotReform.getParkLotInfo(), userId);
//        //更新分派任务状态
//        List<AssignTaskItemDTO> taskItems = parkLotReform.getAssignTaskItems();
//        List<ParkLotRecordAssignTaskItem> items = BeanMapper.mapList(taskItems, ParkLotRecordAssignTaskItem.class);
//        parkLotRecordAssignTaskItemMapper.updateById(items);
//        //更新文件
        return true;
    }

    @Override
    public boolean deleteParkLotRecord(int parkTaskId) {
        //删除任务表中的数据
        parkLotRecordTaskMapper.deleteByPrimaryKey(parkTaskId);
        //删除备份数据
        parkLotRecordTaskLastChangeMapper.deleteByTaskId(parkTaskId);
        return true;
    }

    @Override
    public boolean cancellationParkLot(int id) {
        return parkLotRecordTaskMapper.cancellationParkLot(id) == 1;
    }


    @Override
    public Map<Integer, AgentCenterDTO> getAgentCenterDTOMap(int districtId) {
        Map<Integer, AgentCenterDTO> map = new HashMap<>();
        RecordProcess recordProcess = recordProcessMapper.findByDistrictId(districtId);
        for (int i = 1; i <= 3; i++) {
            List<AuditStatusDTO> auditStatus = parkLotRecordTaskMapper.getAuditStatus(i, districtId);
            map.put(i, new AgentCenterDTO());
            //已处理
            List<ParkLotRecordProcessHistory> history = parkLotRecordProcessHistoryMapper.findByStageAndDistrictId(i, districtId);
            map.get(i).setHandled(history.size());
            handleData(auditStatus, map, i, 1, Integer.parseInt(recordProcess.getNodeDays()));
        }
        return map;
    }

    /**
     * 对代办中心的数据进行处理
     *
     * @param auditStatus
     * @param map
     * @param stage
     * @param addNumber
     */
    public void handleData(List<AuditStatusDTO> auditStatus, Map<Integer, AgentCenterDTO> map, int stage, int addNumber, int nodeDays) {
        for (AuditStatusDTO status : auditStatus) {
            //待处理
            if (status.getAuditStatus() == 1 || status.getAuditStatus() == 3 || status.getAuditStatus() == 5) {
                map.get(stage).setPending(map.get(stage).getPending() + addNumber);
            }
            //已退回
            if (status.getAuditStatus() == 2 || status.getAuditStatus() == 4 || status.getAuditStatus() == 6) {
                map.get(stage).setReturned(map.get(stage).getReturned() + addNumber);
            }
            long daysBetween = daysBetween(new Date(), status.getSubmitedAt());
            //即将过期
            long remainDays = nodeDays - daysBetween;
            if (0 <= remainDays && remainDays <= 2) {
                map.get(stage).setOverTiming(map.get(stage).getOverTiming() + addNumber);
            }
            //已过期
            if (remainDays < 0) {
                map.get(stage).setOverTimed(map.get(stage).getOverTimed() + addNumber);
            }
        }
    }

    /**
     * 计算两个日期的间隔天数
     *
     * @param one
     * @param two
     * @return
     */
    private static long daysBetween(Date one, Date two) {
        long difference = (one.getTime() - two.getTime()) / 86400000;
        return Math.abs(difference);
    }

    @Override
    public List<ManageParkRecordListDTO> getManageAuditList(int stage, int index, int distinctId, int page, int size) {
        int pageIndex = (page - 1) * size;
        List<ManageParkRecordListDTO> list = parkLotRecordTaskMapper.getManageParkRecordListDTO(distinctId, pageIndex, size);
        List<ManageParkRecordListDTO> result = new ArrayList<>();
        //已完成
        if (index == 4) {
            List<ParkLotRecordProcessHistory> historyList = parkLotRecordProcessHistoryMapper.findByStageAndDistrictId(stage, distinctId);
            for (ManageParkRecordListDTO manageParkRecordListDTO : list) {
                for (ParkLotRecordProcessHistory parkLotRecordProcessHistory : historyList) {
                    if (manageParkRecordListDTO.getId() == parkLotRecordProcessHistory.getParkLotRecordTaskId()) {
                        result.add(manageParkRecordListDTO);
                    }
                }
            }
        }

        //过期处理，即将过期处理，过期处理
        if (index == 1 || index == 2 || index == 3) {
            for (ManageParkRecordListDTO dto : list) {
                int auditStatus = dto.getAuditStatus();
                if ((auditStatus == 1 || auditStatus == 3 || auditStatus == 5) && stage == dto.getStage()) {
                    result.add(dto);
                }
            }
        }

        //已退回（审核不通过）
        if (index == 5) {
            for (ManageParkRecordListDTO dto : list) {
                int auditStatus = dto.getAuditStatus();
                if ((auditStatus == 2 || auditStatus == 4 || auditStatus == 6) && stage == dto.getStage()) {
                    result.add(dto);
                }
            }
        }
        return result;
    }

    @Override
    public List<ParkLotRecordManageResultDTO> getManageResultList(ParkLotRecordManageQueryDTO parkLotRecordManageQueryDTO) {
        return parkLotRecordTaskMapper.getManageResultList(parkLotRecordManageQueryDTO);
    }
}
